﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using ProyectoSelva.Const;
using ProyectoSelva.Daos;
using EntitiesAndMappings.Entities;
using ProyectoSelva.Validate;

namespace ProyectoSelva.Forms.Mantenimiento
{
    public partial class FrmActualizarContrato : Form,IValidateForm
    {
        public Boolean CerroSinAccion { get; set; }

        private Contrato contrato;

        private Boolean _valido;

        public FrmActualizarContrato(Contrato contrato)
        {
            CerroSinAccion = false;
            InitializeComponent();
            _valido = true;
            this.contrato = contrato;
            if (contrato.Trabajador == null)
            {
                this.contrato.Trabajador = new Trabajador();
            }
        }

        private void btnAceptar_Click(object sender, EventArgs e)
        {
            _valido = true;
            errorProvider.Clear();
            FormsAssert.AssertTextBoxNotEmptyAndSize(txtNumeroDocumento, 10, errorProvider, this);
            FormsAssert.AssertComboBoxSelected(cmbTipoDocumento,errorProvider,this);
            FormsAssert.AssertComboBoxSelected(cmbEmpresa,errorProvider,this);
            FormsAssert.AssertComboBoxSelected(cmbProyecto,errorProvider,this);
            FormsAssert.AssertComboBoxSelected(cmbLote,errorProvider,this);
            FormsAssert.AssertComboBoxSelected(cmbCargo,errorProvider,this);
            FormsAssert.AssertTextBoxOnlyNumbersDecimal(txtSueldo,errorProvider,this);
            FormsAssert.AssertComboBoxSelected(cmbEstatus,errorProvider,this);
            if (datFechaInicio.Value>=datFechaTermino.Value)
            {
                errorProvider.SetError(datFechaTermino,@"La fecha de termino debe ser mayor que la fecha de inicio");
                Invalid();
            }
            if (contrato.MotivoLiquidacion != null )
            {
                if (datFechaLiquidacion.Value.Date > datFechaTermino.Value.Date)
                {
                    errorProvider.SetError(datFechaLiquidacion,@"La fecha de liquidación debe ser menor o igual a la fecha de fin del contrato");
                    Invalid();
                }
                if (datFechaLiquidacion.Value.Date <= datFechaInicio.Value.Date)
                {
                    errorProvider.SetError(datFechaLiquidacion, @"La fecha de liquidación debe ser mayor a la fecha de inicio del contrato");
                    Invalid();
                }
            }
            ActionExecutor.Execute(this, delegate
            {
                var trabajadorDAO = new TrabajadorDAO();
                var trabajadores = trabajadorDAO.Buscar(new Trabajador
                {
                    NumeroDocumento = txtNumeroDocumento.Text,
                    TipoDocumento = cmbTipoDocumento.SelectedItem as TipoDocumento
                });
                if (trabajadores.Count==1)
                {
                    contrato.Trabajador = trabajadores[0];
                    contrato.Empresa = cmbEmpresa.SelectedItem as Empresa;
                    contrato.Proyecto = cmbProyecto.SelectedItem as Proyecto;
                    contrato.Lote = cmbLote.SelectedItem as Lote;
                    contrato.TipoCargo = cmbCargo.SelectedItem as TipoCargo;
                    contrato.Sueldo = double.Parse(txtSueldo.Text);
                    contrato.StatusContrato = cmbEstatus.SelectedItem as StatusContrato;
                    contrato.FechaInicioContrato = datFechaInicio.Value.Date;
                    contrato.FechaTerminoContrato = datFechaTermino.Value.Date;
                    contrato.Observaciones = txtObservaciones.Text;
                    contrato.Estado = Estado.Activo;
                    contrato.Usuario = FrmInicioSelva.Usuario.Nombre;
                    if (contrato.MotivoLiquidacion !=null)
                    {
                        contrato.FechaLiquidacion = datFechaLiquidacion.Value.Date;
                    }
                    var contratoDAO = new ContratoDAO();
                    if (contratoDAO.EsValido(contrato))
                    {
                        contratoDAO.Actualizar(contrato);
                        Close();
                    }
                    else
                    {
                        throw new ApplicationException(@"El contrato ingresado no puede ser registrado, verifique que no exista otro contrato activo");
                    }
                    
                }
                else
                {
                    if (trabajadores.Count>1)
                    {
                        throw new ApplicationException(@"Se encontro más de un trabajador con el número de documento ingresado");
                    }
                    if (trabajadores.Count==0)
                    {
                        throw new ApplicationException(@"No se encontró ningun trabajador con el número de documento ingresado");
                    }
                }
            });
        }
        
        private void FrmActualizarContrato_Load(object sender, EventArgs e)
        {
            txtNumeroDocumento.Text = contrato.Trabajador.NumeroDocumento;
            txtSueldo.Text = contrato.Sueldo.ToString();
            txtObservaciones.Text = contrato.Observaciones;
            txtObservacionRenovacion.Text = contrato.ObservacionesRenovacion;
            txtObservacionRenovacion.Enabled = false;
            if (contrato.FechaInicioContrato != null) 
                datFechaInicio.Value = contrato.FechaInicioContrato.Value.Date;
            if (contrato.FechaTerminoContrato != null) 
                datFechaTermino.Value = contrato.FechaTerminoContrato.Value.Date;
            if (contrato.FechaLiquidacion != null) 
                datFechaLiquidacion.Value = contrato.FechaLiquidacion.Value.Date;
            if (contrato.MotivoLiquidacion!=null)
            {
                lblMotivoLiquidacion.Text = contrato.MotivoLiquidacion.Descripcion;
            }
            else
            {
                datFechaLiquidacion.Enabled = false;
            }
            if (contrato.FechaIngresoCampo != null && !DateTime.MinValue.Equals(contrato.FechaIngresoCampo))
            {
                lblFechaIngresoCampo.Text = contrato.FechaIngresoCampo.Value.ToString("dd/MM/yyyy");
            }
            if (contrato.FechaSalidaCampo != null && !DateTime.MinValue.Equals(contrato.FechaSalidaCampo))
            {
                lblFechaSalidaCampo.Text = contrato.FechaSalidaCampo.Value.ToString("dd/MM/yyyy");
            }
            ActionExecutor.Execute(this, delegate
            {
                var tipoDocumentoDAO = new EntidadGenericaDAO<TipoDocumento>();
                var listado = tipoDocumentoDAO.ListarActivos();
                cmbTipoDocumento.DataSource = listado;
                if (contrato.Trabajador != null)
                {
                    cmbTipoDocumento.SelectedIndex = ObtenerIndiceCombo(listado, contrato.Trabajador.TipoDocumento);
                }
            });
            ActionExecutor.Execute(this, delegate
            {
                var empresaDAO = new EntidadGenericaDAO<Empresa>();
                var listado = empresaDAO.ListarActivos();
                cmbEmpresa.DataSource = listado;
                cmbEmpresa.SelectedIndex = ObtenerIndiceCombo(listado, contrato.Empresa);
            });
            ActionExecutor.Execute(this, delegate
            {
                var proyectoDAO = new EntidadGenericaDAO<Proyecto>();
                var listado= proyectoDAO.ListarActivos();
                cmbProyecto.DataSource = listado;
                cmbProyecto.SelectedIndex = ObtenerIndiceCombo(listado, contrato.Proyecto);
            });
            ActionExecutor.Execute(this, delegate
            {
                var loteDAO = new EntidadGenericaDAO<Lote>();
                var listado = loteDAO.ListarActivos();
                cmbLote.DataSource = listado;
                cmbLote.SelectedIndex = ObtenerIndiceCombo(listado, contrato.Lote);
            });
            ActionExecutor.Execute(this, delegate
            {
                var cargoDAO = new EntidadGenericaDAO<TipoCargo>();
                var listado = cargoDAO.ListarActivos();
                cmbCargo.DataSource = listado;
                cmbCargo.SelectedIndex = ObtenerIndiceCombo(listado, contrato.TipoCargo);
            });
            ActionExecutor.Execute(this, delegate
            {
                var estatusDAO = new EntidadGenericaDAO<StatusContrato>();
                var listado = estatusDAO.ListarActivos();
                cmbEstatus.DataSource = listado;
                cmbEstatus.SelectedIndex = ObtenerIndiceCombo(listado, contrato.StatusContrato);
            });
        }

        private int ObtenerIndiceCombo<T>(IList<T> listado, T referencia)
        {
            var valor = referencia as EntidadGenerica;
            var indice = 0;
            if (valor != null)
            {
                var temporal = listado[indice] as EntidadGenerica;
                if (temporal != null)
                {
                    while (listado.Count > indice && valor.Id!=temporal.Id)
                    {
                        indice++;
                        temporal = listado[indice] as EntidadGenerica;
                    }
                }
            }
            return indice;
        }

        public void Invalid()
        {
            _valido = false;
        }

        public Boolean IsValid()
        {
            return _valido;
        }

        private void FrmActualizarTrabajador_FormClosing(object sender, FormClosingEventArgs e)
        {
            CerroSinAccion = (contrato.Id==0);
        }
    }
}
